//
//  Cliqset.m
//  cliqset
//
//  Created by David Hinson on 2/17/09.
//  Copyright 2009 Sumner Systems Management, Inc.. All rights reserved.
//

#import "Cliqset.h"
#import "cliqsetAppDelegate.h"
#import "XMLReader.h"
#import "ParseEventXMLReader.h"
#import "ParseProfileXMLReader.h"
#import "ParseStatusXMLReader.h"

@implementation Cliqset

@synthesize currentContact;
@synthesize currentType;
@synthesize currentField;
@synthesize currentFlag;
@synthesize isFavorite;

@synthesize currentStreet;
@synthesize currentLocality;
@synthesize currentRegion;
@synthesize currentPostalCode;
@synthesize currentCountry;

@synthesize currentContactRecord;

#pragma mark ---- authentication ----

// For getting strings from Settings Bundle
NSString *kloginKey			= @"loginKey";
NSString *kpasswordKey		= @"passwordKey";

// Consumer key from cliqset
NSString *consumerKey       = @"PUT_CONSUMER_KEY_HERE";

/*
 ** Global data used by both binary-to-base64 and base64-to-binary conversions
 */

static char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789"
"+/";

int encode(unsigned s_len, char *src, unsigned d_len, char *dst)
{
	unsigned triad;
	
	for (triad = 0; triad < s_len; triad += 3)
	{
		unsigned long int sr;
		unsigned byte;
		
		for (byte = 0; (byte<3)&&(triad+byte<s_len); ++byte)
		{
			sr <<= 8;
			sr |= (*(src+triad+byte) & 0xff);
		}
		
		sr <<= (6-((8*byte)%6))%6; /*shift left to next 6bit alignment*/
		
		if (d_len < 4) return 1; /* error - dest too short */
		
		*(dst+0) = *(dst+1) = *(dst+2) = *(dst+3) = '=';
		switch(byte)
		{
			case 3:
				*(dst+3) = base64[sr&0x3f];
				sr >>= 6;
			case 2:
				*(dst+2) = base64[sr&0x3f];
				sr >>= 6;
			case 1:
				*(dst+1) = base64[sr&0x3f];
				sr >>= 6;
				*(dst+0) = base64[sr&0x3f];
		}
		dst += 4; d_len -= 4;
	}
	
	return 0;
	
}

// Init Cliqset
-(Cliqset*)init {
	self = [super init];	
	return self;
}

// Authenticate the user
-(void)authenticate {

	cliqsetAppDelegate* myApp = (cliqsetAppDelegate*)[[UIApplication sharedApplication] delegate];

	myApp.loginString    = (NSMutableString*)[[NSUserDefaults standardUserDefaults] stringForKey:kloginKey];
	myApp.passwordString = (NSMutableString*)[[NSUserDefaults standardUserDefaults] stringForKey:kpasswordKey];

	[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
	
	NSMutableString *dataStr = (NSMutableString*)[@"" stringByAppendingFormat:@"%@:%@", myApp.loginString, myApp.passwordString];
	
	NSData *encodeData = [dataStr dataUsingEncoding:NSUTF8StringEncoding];
	char encodeArray[512];
	memset(encodeArray,'\0', sizeof(encodeArray));
	
	// Base64 Encode username and password
	encode([encodeData length], (char *)[encodeData bytes], sizeof(encodeArray), encodeArray);	
	
	dataStr = [NSString stringWithCString:encodeArray length:strlen(encodeArray)];	
	myApp.authenticationString = [@"" stringByAppendingFormat:@"Basic %@", dataStr];
	
	myApp.isAuthenticated  = NO;
	myApp.isAuthenticating = YES;
	
	Connector * connector = [[[Connector alloc] init] autorelease];
	
	connector.mode   = 0;
	connector.parent = self;
	
	// Create asyncronous request
	connector.theRequest=(NSMutableURLRequest*)[NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://api.cliqset.com/user/useridentifier"] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];	
	[connector.theRequest addValue:myApp.authenticationString forHTTPHeaderField:@"Authorization"];
	[connector.theRequest addValue:consumerKey forHTTPHeaderField:@"CliqsetConsumerKey"];
	
	connector.theConnection=[[NSURLConnection alloc] initWithRequest:connector.theRequest delegate:connector];
	
	[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
	if (connector.theConnection) {
		connector.receivedData = [[NSMutableData data] retain];
		} 
	else {
		[myApp addTextToLog:@"Could not connect to the network" withCaption:@"cliqset"];
		}
}

// Do logout
-(void)logout {
	cliqsetAppDelegate* myApp            = (cliqsetAppDelegate*)[[UIApplication sharedApplication] delegate];
	NSUserDefaults *standardUserDefaults = (NSUserDefaults *)[NSUserDefaults standardUserDefaults];

	// Clear credentials fields
	[standardUserDefaults setObject:@"" forKey:kloginKey];
	[standardUserDefaults setObject:@"" forKey:kpasswordKey];
	
	myApp.loginString          = @"";
	myApp.passwordString       = @"";
	myApp.authenticationString = @"";
	
	// Reset current profile
	if (myApp.currentProfile) {
		[myApp.currentProfile release];
		myApp.currentProfile = nil;
	}
	
	[myApp flipSplashToFront];
	
	// Clear internal contacts table
	// myApp.contacts = [[NSMutableArray alloc] init];
	[myApp.contacts removeAllObjects];
	
	// Clean the screen of contacts
	[myApp reloadContactsTable];
	
	// Clear the database
	[myApp.database saveContactsToDatabase];

	// Reset the timestamp
	[myApp.database resetTimestamp];
	
	[self authenticate];
}

// Is this an error?
-(BOOL)isError:(NSString*)dataStr {
	cliqsetAppDelegate* myApp = (cliqsetAppDelegate*)[[UIApplication sharedApplication] delegate];
	
	if ([dataStr isEqualToString:@"Error 500"]) {
		//[myApp addTextToLog:dataStr withCaption:@"Error 500.  Server error."];
		[myApp addTextToLog:@"Server Error" withCaption:@"cliqset"];
		return YES;
	}
	if ([dataStr isEqualToString:@"Error 400"]) {
		// [myApp addTextToLog:dataStr withCaption:@"Error 400.  Bad Request."];
		[myApp addTextToLog:@"Bad Request" withCaption:@"cliqset"];
		return YES;
	}
	if ([dataStr isEqualToString:@"Error 401"]) {
		//[myApp addTextToLog:dataStr withCaption:@"Error 401.  Unauthorized."];
		[myApp addTextToLog:@"Unauthorized" withCaption:@"cliqset"];
		return YES;
	}
	if ([dataStr isEqualToString:@"Error 403"]) {
		//[myApp addTextToLog:dataStr withCaption:@"Error 403.  You are not permitted to use this resource."];
		[myApp addTextToLog:@"You Are Not Permitted To Do This" withCaption:@"cliqset"];
		return YES;
	}
	if ([dataStr isEqualToString:@"Error 404"]) {
		//[myApp addTextToLog:dataStr withCaption:@"Error 404.  Item does not exist."];
		[myApp addTextToLog:@"Item Does Not Exist" withCaption:@"cliqset"];
		return YES;
	}
	
	return NO;
}

-(void)processMessage:(NSData*)data mode:(int)mode {

	cliqsetAppDelegate* myApp = (cliqsetAppDelegate*)[[UIApplication sharedApplication] delegate];
		
	NSMutableString* workMe;
	NSString *dataStr          = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
	NSAutoreleasePool *pool    = [[NSAutoreleasePool alloc] init];			
	NSError *parseError        = nil;	
	
	XMLReader *streamingParser              = [[XMLReader alloc] init];
	ParseEventXMLReader *streamingParser2   = [[ParseEventXMLReader alloc] init];
	ParseStatusXMLReader *streamingParser3  = [[ParseStatusXMLReader alloc] init];
	ParseProfileXMLReader *streamingParser4 = [[ParseProfileXMLReader alloc] init];
	
	if (mode==0 && [dataStr length] < 10) {		
		[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
		[dataStr release];
		//[connection release];
		//[[self.receivedDataArray objectAtIndex:self.mode] release];	
		myApp.isAuthenticating = YES;
		myApp.isAuthenticated  = NO;
		[myApp flipLoginToFront];
		
		if (myApp.loginString && myApp.passwordString && !([myApp.loginString isEqualToString:@""] && [myApp.passwordString isEqualToString:@""])) {
			[myApp addTextToLog:@"Please re-enter your Username and Password" withCaption:@"Login"];
		}
		
		return;
	}
	
	switch (mode) {
		case 0:
			// Mode 0: get user identifier
			// Extract the user identification string
			workMe          = (NSMutableString*)dataStr;
			workMe          = (NSMutableString*)[[workMe stringByReplacingOccurrencesOfString:@"</UserIdentifier>" withString:@""] stringByReplacingOccurrencesOfString:@"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><UserIdentifier>" withString:@""];
			myApp.userString = workMe;
			
			// Remove splash screen
			if (myApp.splashViewController) {
				[myApp flipSplashToBack];
				myApp.splashViewController = nil;
				}

			// Load To Events for front page
			[self loadToEvents];
			
			// Get profile
			[self getProfile];
			
			// Get current status
			[self getCurrentStatus];
			
			// Load Profile Events
			[self loadProfileEvents:myApp.userString reload:YES];

			// Load Contacts
			[self getUserContacts:myApp.userString];
			
			// Retrieve a user's contacts, if needed
			//if ([myApp.database databaseNeedsUpdate]) {
			//	[myApp.cliqset getUserContacts:myApp.userString];
			//	}
			//else {
			//	mode = 0;
			//	[myApp.database loadContactsFromDatabase:myApp.userString];
				
			//	[myApp reloadContactsTable];
				
			//	[myApp.database loadFavorites:myApp.userString];
				
				// Turn off network busy indicator... we're done for now
			//	[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
				
			//	myApp.isAuthenticating = NO;
			//	myApp.isAuthenticated  = YES;
			//	}
			
			myApp.isAuthenticating = NO;
			myApp.isAuthenticated  = YES;
			
			[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
			break;
			
		case 1:
			// Mode 1: get a user's contacts
			// Deserialize returned XML
			
			if (![self isError:dataStr]) {

				// Clear contacts array
				[myApp.contacts removeAllObjects];
				
				[streamingParser parseXMLFileAtData:data parseError:&parseError];
			
				// For testing XML deserialization for contacts
				if (0) {
				
				for (int x=0; x<[myApp.contacts count]; x++) {
					Contact *deref = (Contact *)[myApp.contacts objectAtIndex:x];
					NSLog(@"\r\n############");
					NSLog(@"Contact ID : %@", deref.contactIdentifier);
					NSLog(@"Given Name : %@", deref.givenName);
					NSLog(@"Middle Name: %@", deref.middleName);
					NSLog(@"Family Name: %@", deref.familyName);
					NSLog(@"Notes      : %@", deref.notes);
					NSLog(@"Company    : %@", deref.company);
					NSLog(@"Position   : %@", deref.position);
					NSLog(@"____________");
					NSLog(@"Tags");
					for (int y=0; y<[deref.tags count]; y++) {
						if ([[deref.tags objectAtIndex:y] isKindOfClass:[NSString class]]) {
							NSLog(@"%@", [deref.tags objectAtIndex:y]);
						}
						if ([[deref.tags objectAtIndex:y] isKindOfClass:[Tag class]]) {
							Tag * tag = (Tag *)[deref.tags objectAtIndex:y];
							NSLog(@"%@\r\n", tag.tag);
						}
					}
					NSLog(@"____________");
					NSLog(@"Phones");
					for (int y=0; y<[deref.phones count]; y++) {
						if ([[deref.phones objectAtIndex:y] isKindOfClass:[Phone class]]) {
							Phone * phone = (Phone *)[deref.phones objectAtIndex:y];
							NSLog(@"Type    : %@", phone.type);
							NSLog(@"Primary?: %d", phone.primary);
							NSLog(@"Number  : %@\r\n", phone.phoneNumber);
						}
					}
					NSLog(@"____________");
					NSLog(@"URLS");
					for (int y=0; y<[deref.urls count]; y++) {
						if ([[deref.urls objectAtIndex:y] isKindOfClass:[URL class]]) {
							URL * url = (URL *)[deref.urls objectAtIndex:y];
							NSLog(@"Type    : %@", url.type);
							NSLog(@"Primary?: %d", url.primary);
							NSLog(@"URL     : %@\r\n", url.url);
						}
					}
					NSLog(@"____________");
					NSLog(@"Addresses");
					for (int y=0; y<[deref.addresses count]; y++) {
						if ([[deref.addresses objectAtIndex:y] isKindOfClass:[Address class]]) {
							Address * address = (Address *)[deref.addresses objectAtIndex:y];
							NSLog(@"Type       : %@", address.type);
							NSLog(@"Primary?   : %d", address.primary);
							NSLog(@"Street     : %@", address.streetAddress);
							NSLog(@"Locality   : %@", address.locality);
							NSLog(@"Region     : %@", address.region);
							NSLog(@"Country    : %@", address.country);
							NSLog(@"PostalCode : %@\r\n", address.postalCode);
						}
					}
					NSLog(@"____________");
					NSLog(@"Email");
					for (int y=0; y<[deref.emailAddresses count]; y++) {
						if ([[deref.emailAddresses objectAtIndex:y] isKindOfClass:[EmailAddress class]]) {
							EmailAddress * email = (EmailAddress *)[deref.emailAddresses objectAtIndex:y];
							NSLog(@"Type    : %@", email.type);
							NSLog(@"Primary?: %d", email.primary);
							NSLog(@"Email   : %@\r\n", email.address);
						}
					}
					NSLog(@"____________");
					NSLog(@"IM");
					for (int y=0; y<[deref.imScreenNames count]; y++) {
						if ([[deref.imScreenNames objectAtIndex:y] isKindOfClass:[IM class]]) {
							IM * im = (IM *)[deref.imScreenNames objectAtIndex:y];
							NSLog(@"Network : %@", im.network);
							NSLog(@"Primary?: %d", im.primary);
							NSLog(@"Name    : %@\r\n", im.name);
						}
					}
				}
				}
				
				NSString * badge = ([myApp.contacts count] == 0) ? nil : [@"" stringByAppendingFormat:@"%d", [myApp.contacts count]];
				[myApp showContactsBadge:badge];
				
				// Write contacts to database
				[myApp.database saveContactsToDatabase];
			
				// Load favorites
				[myApp.database loadFavorites:myApp.userString];
				
				// Clear all in memory, now let's reload from database
				[myApp.contacts removeAllObjects];
				
				// Load contacts from the database
				[myApp.database loadContactsFromDatabase:myApp.userString];
			
				// Reload contacts table
				[myApp reloadContactsTable];
				
				// Reset hover view
				[myApp showContactsHoverView:NO];
				}
			
			[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
			
			break;
			
		case 2:
			// Delete contact
			if (![self isError:dataStr]) {
				// No body means we are gold
				if ([dataStr length] == 0) {
					// Remove contact (and any favorite tagged)
					[myApp.database removeContact:myApp.userString cid:self.currentContact];
					[myApp.database loadContactsFromDatabase:myApp.userString];
					
					// Set filter back to "All"
					[myApp resetSegment];
					
					[myApp reloadContactsTable];
					[myApp slideFavoriteOut];
					[myApp reloadFavoritesTable];
					[myApp showContactsHoverView:NO];
					//[myApp showFavoritesHoverView];
					}
				}
			
			[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
			break;
			
		case 3:
			// Delete user email
			if (![self isError:dataStr]) {
				// No body means we are gold
				if ([dataStr length] == 0) {
					[myApp.database removeEmailAddress:myApp.userString cid:self.currentContact tag:self.currentType];
					}
				}
			
			[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
			break;
			
		case 4:
			// Delete user address
			if (![self isError:dataStr]) {
				// No body means we are gold
				if ([dataStr length] == 0) {
					[myApp.database removeAddress:myApp.userString cid:self.currentContact tag:self.currentType];
				}
			}
			
			[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
			break;
			
		case 5:
			// Delete user phone
			if (![self isError:dataStr]) {
				// No body means we are gold
				if ([dataStr length] == 0) {
					[myApp.database removePhone:myApp.userString cid:self.currentContact tag:self.currentType];
				}
			}
			[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
			break;
			
		case 6:
			// Delete user IM
			if (![self isError:dataStr]) {
				// No body means we are gold
				if ([dataStr length] == 0) {
					[myApp.database removeIM:myApp.userString cid:self.currentContact tag:self.currentType];
				}
			}
			
			[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
			break;
			
		case 7:
			// Delete user URL
			if (![self isError:dataStr]) {
				// No body means we are gold
				if ([dataStr length] == 0) {
					[myApp.database removeURL:myApp.userString cid:self.currentContact tag:self.currentType];
				}
			}
			
			[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
			break;
			
		case 8:
			
			// Put user phone
			if (![self isError:dataStr]) {
				// No body means we are gold
				if ([dataStr length] == 0) {
					[myApp.database putPhone:myApp.userString cid:self.currentContact tag:self.currentType content:self.currentField flag:self.currentFlag];
				}
			}
			
			[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
			break;
			
		case 9:
			
			// Put user url
			if (![self isError:dataStr]) {
				// No body means we are gold
				if ([dataStr length] == 0) {
					[myApp.database putURL:myApp.userString cid:self.currentContact tag:self.currentType content:self.currentField];
				}
			}
			
			[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
			break;
			
		case 10:
			
			// Put user email
			if (![self isError:dataStr]) {
				// No body means we are gold
				if ([dataStr length] == 0) {
					[myApp.database putEmailAddress:myApp.userString cid:self.currentContact tag:self.currentType content:self.currentField flag:self.currentFlag];
				}
			}
			
			[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
			break;
			
		case 11:
			
			// Put user IM
			if (![self isError:dataStr]) {
				// No body means we are gold
				if ([dataStr length] == 0) {
					[myApp.database putIM:myApp.userString cid:self.currentContact tag:self.currentType content:self.currentField flag:self.currentFlag];
				}
			}
			
			[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
			break;
			
		case 12:
			
			// Put Contact Address
			if (![self isError:dataStr]) {
				// No body means we are gold
				if ([dataStr length] == 0) {
					[myApp.database putAddress:myApp.userString cid:self.currentContact tag:self.currentType street:self.currentStreet locality:self.currentLocality region:self.currentRegion postalCode:self.currentPostalCode country:self.currentCountry];
				}
			}
			
		case 13:
			
			// Put Contact Record
			if (![self isError:dataStr]) {
				// No body means we are gold
				if ([dataStr length] == 0) {
					// NSMutableString* since = @"20090219T00:00-00:00";
					if (self.currentContactRecord.contactIdentifier == nil) {
						// Remove all contacts
						[myApp.contacts removeAllObjects];						
						[myApp.cliqset getUserContacts:myApp.userString];
						}
					else {
						[myApp.database putContact:currentContactRecord];
					}
				}
			}
			
			[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
			break;
			
		case 14:
			// Get TO events Record
			if (![self isError:dataStr]) {
				
				NSLog(@"%@", dataStr);
				
				// Make sure the array is empty
				[myApp.toEvents removeAllObjects];
				
				streamingParser2.mode = mode;
				[streamingParser2 parseXMLFileAtData:data parseError:&parseError];
			
				// OK... while we're here, let's populate any picture blobs we might have, too.
				for (int x=0; x<[myApp.toEvents count]; x++) {
					Event * event = [myApp.toEvents objectAtIndex:x];
					for (int y=0; y<[event.resources count]; y++) {
						Resource * resource = [event.resources objectAtIndex:y];
						if ([resource.name isEqualToString:@"Thumbnail-1"] ||
							[resource.name isEqualToString:@"Thumbnail-2"] ||
							[resource.name isEqualToString:@"Thumbnail-3"] ||
							[resource.name isEqualToString:@"Thumbnail-4"] ||
							[resource.name isEqualToString:@"Thumbnail-5"]) {
							resource.blob = (NSMutableData*)[NSData dataWithContentsOfURL: [NSURL URLWithString: resource.value]]; 
						}
					}
				}
				
				NSString * badge = ([myApp.toEvents count] == 0) ? nil : [@"" stringByAppendingFormat:@"%d", [myApp.toEvents count]];
				[myApp showEventsBadge:badge];
				
				// Save grabbed events to database, inserting any new ones
				[myApp.database saveEventsToDatabase];

				// Again, make sure the in memory array is empty
				[myApp.toEvents removeAllObjects];

				// And then, load last 25 from the database.
				[myApp.database loadEventsFromDatabase:myApp.userString];

				// Reload events table
                [myApp reloadEventsTable];		
				[myApp showEventsHoverView:NO];
			} else {
				[myApp showEventsHoverView:NO];
			}

			[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
			break;
			
		case 15:
			// Get FROM events Record
			if (![self isError:dataStr]) {
				
				// Make sure the array is empty
				[myApp.fromEvents removeAllObjects];
				
				streamingParser2.mode = mode;
				[streamingParser2 parseXMLFileAtData:data parseError:&parseError];
				
				// OK... while we're here, let's populate any picture blobs we might have, too.
				for (int x=0; x<[myApp.fromEvents count]; x++) {
					Event * event = [myApp.fromEvents objectAtIndex:x];
					for (int y=0; y<[event.resources count]; y++) {
						Resource * resource = [event.resources objectAtIndex:y];
						if ([resource.name isEqualToString:@"Thumbnail-1"] ||
							[resource.name isEqualToString:@"Thumbnail-2"] ||
							[resource.name isEqualToString:@"Thumbnail-3"] ||
							[resource.name isEqualToString:@"Thumbnail-4"] ||
							[resource.name isEqualToString:@"Thumbnail-5"]) {
							resource.blob = (NSMutableData*)[NSData dataWithContentsOfURL: [NSURL URLWithString: resource.value]]; 
						}
					}
				}
				
				// Reload events table
                [myApp reloadEventsTable];		
				[myApp showEventsHoverView:NO];
			} else {
				[myApp showEventsHoverView:NO];
			}
			
			[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
			break;
			
		case 16:
			
			// Get Current Status
			if (![self isError:dataStr]) {
				// Parse Status
				[streamingParser3 parseXMLFileAtData:data parseError:&parseError];
			}
			[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
			break;
			
		case 17:
			
			// Put Current Status
			if (![self isError:dataStr]) {
				// Schedule a profile reload
				// bScheduledProfileEvents = YES;
			}
			[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
			break;
			
		case 18:
			
			// Get Profile
			if (![self isError:dataStr]) {
				// Parse Profile
				[streamingParser4 parseXMLFileAtData:data parseError:&parseError];
				[myApp reloadProfileTable];
			}
			
			[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
			break;
			
		case 19:
			
			// Get Profile "Profile" Events
			if (![self isError:dataStr]) {
				
				// Make sure the array is empty
				[myApp.profileEvents removeAllObjects];
				
				streamingParser2.mode = mode;
				[streamingParser2 parseXMLFileAtData:data parseError:&parseError];
				
				// OK... while we're here, let's populate any picture blobs we might have, too.
				for (int x=0; x<[myApp.profileEvents count]; x++) {
					Event * event = [myApp.profileEvents objectAtIndex:x];
					for (int y=0; y<[event.resources count]; y++) {
						Resource * resource = [event.resources objectAtIndex:y];
						if ([resource.name isEqualToString:@"Thumbnail-1"] ||
							[resource.name isEqualToString:@"Thumbnail-2"] ||
							[resource.name isEqualToString:@"Thumbnail-3"] ||
							[resource.name isEqualToString:@"Thumbnail-4"] ||
							[resource.name isEqualToString:@"Thumbnail-5"]) {
							resource.blob = (NSMutableData*)[NSData dataWithContentsOfURL: [NSURL URLWithString: resource.value]]; 
						}
					}
				}
				
				// Reload events table
                [myApp reloadProfileTable];		
				[myApp showProfileHoverView:NO];
			} else {
				[myApp showProfileHoverView:NO];
			}
			
			[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
			break;
			
		default:
			[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
			break;
	}
	
	[streamingParser release]; 
	[streamingParser2 release]; 
	[streamingParser3 release]; 
	[streamingParser4 release]; 
	
	[dataStr release];
	[pool release];
}

// Get all user's updated since ISO8601 date
-(void)getUserContacts:(NSString*)userid since:(NSString*)since {
	cliqsetAppDelegate* myApp = (cliqsetAppDelegate*)[[UIApplication sharedApplication] delegate];
	
	Connector * connector = [[[Connector alloc] init] autorelease];
	
	connector.mode   = 14;
	connector.parent = self;
	
	connector.theRequest=(NSMutableURLRequest*)[NSMutableURLRequest requestWithURL:[NSURL URLWithString:[@"" stringByAppendingFormat:@"https://api.cliqset.com/user/%@/contacts?start=0&count=1000&updatedsince=%@", myApp.userString, since]] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];	
	[connector.theRequest addValue:myApp.authenticationString forHTTPHeaderField:@"Authorization"];
	[connector.theRequest addValue:consumerKey forHTTPHeaderField:@"CliqsetConsumerKey"];
	
	connector.theConnection=[[NSURLConnection alloc] initWithRequest:connector.theRequest delegate:connector];
	
	[myApp showContactsHoverView:YES];
	[myApp showEventsHoverView:YES];
	[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
	if (connector.theConnection) {
		connector.receivedData=[[NSMutableData data] retain];		
		} 
	else {
		[myApp addTextToLog:@"Could not connect to the network" withCaption:@"cliqset"];
		}	
}

// Get user contacts
-(void)getUserContacts:(NSString*)userid {
	cliqsetAppDelegate* myApp = (cliqsetAppDelegate*)[[UIApplication sharedApplication] delegate];

	Connector * connector = [[[Connector alloc] init] autorelease];
	
	connector.mode   = 1;
	connector.parent = self;
	
	NSString * url;
	if ([myApp.database countContactsFromDatabase] == 0) {
		url = [@"" stringByAppendingFormat:@"https://api.cliqset.com/user/%@/contacts?start=0&count=1000", myApp.userString];
		} 
	else {
		url = [@"" stringByAppendingFormat:@"https://api.cliqset.com/user/%@/contacts?start=0&count=1000&updatedsince=%@", myApp.userString, [myApp.database getLatestContactDateFromDatabase]];
		}
	
	//NSLog(@"get contacts url: %@", url);
	
	connector.theRequest=(NSMutableURLRequest*)[NSMutableURLRequest requestWithURL:[NSURL URLWithString:url] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];	
	[connector.theRequest addValue:myApp.authenticationString forHTTPHeaderField:@"Authorization"];
	[connector.theRequest addValue:consumerKey forHTTPHeaderField:@"CliqsetConsumerKey"];
	
	connector.theConnection=[[NSURLConnection alloc] initWithRequest:connector.theRequest delegate:connector];
	
	[myApp showContactsHoverView:YES];
	[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
	if (connector.theConnection) {
		connector.receivedData=[[NSMutableData data] retain];		
		} 
	else {
		[myApp addTextToLog:@"Could not connect to the network" withCaption:@"cliqset"];
		}	
}

// Delete a user's contact
-(void)deleteUserContact:(NSString*)cid isFavorite:(BOOL)favorite {
	cliqsetAppDelegate* myApp = (cliqsetAppDelegate*)[[UIApplication sharedApplication] delegate];
	
	// Show busy indicator
	if (favorite) {
		[myApp showFavoritesHoverView];
	}
	else {
		[myApp showContactsHoverView:YES];
	}
	
	self.isFavorite = favorite;
	
	self.currentContact = (NSMutableString*)cid;
	
	NSString *url = [@"" stringByAppendingFormat:@"https://api.cliqset.com/user/%@/contacts/%@", myApp.userString, cid];
	
	Connector * connector = [[[Connector alloc] init] autorelease];
	
	connector.mode   = 2;
	connector.parent = self;
	
	connector.theRequest=(NSMutableURLRequest*)[NSMutableURLRequest requestWithURL:[NSURL URLWithString:url] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];	
	
	[connector.theRequest setHTTPMethod:@"DELETE"];
	
	[connector.theRequest addValue:myApp.authenticationString forHTTPHeaderField:@"Authorization"];
	[connector.theRequest addValue:consumerKey forHTTPHeaderField:@"CliqsetConsumerKey"];
	
	connector.theConnection=[[NSURLConnection alloc] initWithRequest:connector.theRequest delegate:connector];
	
	[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
	if (connector.theConnection) {
		connector.receivedData=[[NSMutableData data] retain];		
		} 
	else {
		[myApp addTextToLog:@"Could not connect to the network" withCaption:@"cliqset"];
		}
}

// Delete an email address by type
-(void)deleteUserEmail:(NSString*)cid tag:(NSString*)tag {
	cliqsetAppDelegate* myApp = (cliqsetAppDelegate*)[[UIApplication sharedApplication] delegate];
	
	self.currentContact = (NSMutableString*)cid;
	self.currentType    = (NSMutableString*)tag;
	
	NSString *url = [@"" stringByAppendingFormat:@"https://api.cliqset.com/user/%@/contacts/%@/emailaddresses/%@", myApp.userString, cid, tag];
	
	Connector * connector = [[[Connector alloc] init] autorelease];
	
	connector.mode   = 3;
	connector.parent = self;
	
	connector.theRequest=(NSMutableURLRequest*)[NSMutableURLRequest requestWithURL:[NSURL URLWithString:url] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];	
	
	[connector.theRequest setHTTPMethod:@"DELETE"];
	
	[connector.theRequest addValue:myApp.authenticationString forHTTPHeaderField:@"Authorization"];
	[connector.theRequest addValue:consumerKey forHTTPHeaderField:@"CliqsetConsumerKey"];
	
	connector.theConnection=[[NSURLConnection alloc] initWithRequest:connector.theRequest delegate:connector];
	
	[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
	if (connector.theConnection) {
		connector.receivedData=[[NSMutableData data] retain];		
		} 
	else {
		[myApp addTextToLog:@"Could not connect to the network" withCaption:@"cliqset"];
		}
}

// Delete an address by type
-(void)deleteUserAddress:(NSString*)cid tag:(NSString*)tag {
	cliqsetAppDelegate* myApp = (cliqsetAppDelegate*)[[UIApplication sharedApplication] delegate];
	
	self.currentContact = (NSMutableString*)cid;
	self.currentType    = (NSMutableString*)tag;
	
	NSString *url = [@"" stringByAppendingFormat:@"https://api.cliqset.com/user/%@/contacts/%@/addresses/%@", myApp.userString, cid, tag];
	
	Connector * connector = [[[Connector alloc] init] autorelease];
	
	connector.mode   = 4;
	connector.parent = self;
	
	connector.theRequest=(NSMutableURLRequest*)[NSMutableURLRequest requestWithURL:[NSURL URLWithString:url] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];	
	
	[connector.theRequest setHTTPMethod:@"DELETE"];
	
	[connector.theRequest addValue:myApp.authenticationString forHTTPHeaderField:@"Authorization"];
	[connector.theRequest addValue:consumerKey forHTTPHeaderField:@"CliqsetConsumerKey"];
	
	connector.theConnection=[[NSURLConnection alloc] initWithRequest:connector.theRequest delegate:connector];
	
	[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
	if (connector.theConnection) {
		connector.receivedData=[[NSMutableData data] retain];		
		} 
	else {
		[myApp addTextToLog:@"Could not connect to the network" withCaption:@"cliqset"];
		}
}

// Delete a phone by type
-(void)deleteUserPhone:(NSString*)cid tag:(NSString*)tag {
	cliqsetAppDelegate* myApp = (cliqsetAppDelegate*)[[UIApplication sharedApplication] delegate];
	
	self.currentContact = (NSMutableString*)cid;
	self.currentType    = (NSMutableString*)tag;
	
	NSString *url = [@"" stringByAppendingFormat:@"https://api.cliqset.com/user/%@/contacts/%@/phones/%@", myApp.userString, cid, tag];
	
	Connector * connector = [[[Connector alloc] init] autorelease];
	
	connector.mode   = 5;
	connector.parent = self;
	
	connector.theRequest=(NSMutableURLRequest*)[NSMutableURLRequest requestWithURL:[NSURL URLWithString:url] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];	
	
	[connector.theRequest setHTTPMethod:@"DELETE"];
	
	[connector.theRequest addValue:myApp.authenticationString forHTTPHeaderField:@"Authorization"];
	[connector.theRequest addValue:consumerKey forHTTPHeaderField:@"CliqsetConsumerKey"];
	
	connector.theConnection=[[NSURLConnection alloc] initWithRequest:connector.theRequest delegate:connector];
	
	[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
	if (connector.theConnection) {
		connector.receivedData=[[NSMutableData data] retain];		
		} 
	else {
		[myApp addTextToLog:@"Could not connect to the network" withCaption:@"cliqset"];
		}
}

// Delete an IM by type
-(void)deleteUserIM:(NSString*)cid tag:(NSString*)tag {
	cliqsetAppDelegate* myApp = (cliqsetAppDelegate*)[[UIApplication sharedApplication] delegate];
	
	self.currentContact = (NSMutableString*)cid;
	self.currentType    = (NSMutableString*)tag;
	
	NSString *url = [@"" stringByAppendingFormat:@"https://api.cliqset.com/user/%@/contacts/%@/ims/%@", myApp.userString, cid, tag];
	
	Connector * connector = [[[Connector alloc] init] autorelease];
	
	connector.mode   = 6;
	connector.parent = self;
	
	connector.theRequest=(NSMutableURLRequest*)[NSMutableURLRequest requestWithURL:[NSURL URLWithString:url] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];	
	
	[connector.theRequest setHTTPMethod:@"DELETE"];
	
	[connector.theRequest addValue:myApp.authenticationString forHTTPHeaderField:@"Authorization"];
	[connector.theRequest addValue:consumerKey forHTTPHeaderField:@"CliqsetConsumerKey"];
	
	connector.theConnection=[[NSURLConnection alloc] initWithRequest:connector.theRequest delegate:connector];
	
	[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
	if (connector.theConnection) {
		connector.receivedData=[[NSMutableData data] retain];		
		} 
	else {
		[myApp addTextToLog:@"Could not connect to the network" withCaption:@"cliqset"];
		}
}

// Delete an URL by type
-(void)deleteUserURL:(NSString*)cid tag:(NSString*)tag {
	cliqsetAppDelegate* myApp = (cliqsetAppDelegate*)[[UIApplication sharedApplication] delegate];
	
	self.currentContact = (NSMutableString*)cid;
	self.currentType    = (NSMutableString*)tag;
	
	NSString *url = [@"" stringByAppendingFormat:@"https://api.cliqset.com/user/%@/contacts/%@/urls/%@", myApp.userString, cid, tag];
	
	Connector * connector = [[[Connector alloc] init] autorelease];
	
	connector.mode   = 7;
	connector.parent = self;
	
	connector.theRequest=(NSMutableURLRequest*)[NSMutableURLRequest requestWithURL:[NSURL URLWithString:url] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];	
	
	[connector.theRequest setHTTPMethod:@"DELETE"];
	
	[connector.theRequest addValue:myApp.authenticationString forHTTPHeaderField:@"Authorization"];
	[connector.theRequest addValue:consumerKey forHTTPHeaderField:@"CliqsetConsumerKey"];
	
	connector.theConnection=[[NSURLConnection alloc] initWithRequest:connector.theRequest delegate:connector];
	
	[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
	if (connector.theConnection) {
		connector.receivedData=[[NSMutableData data] retain];		
		} 
	else {
		[myApp addTextToLog:@"Could not connect to the network" withCaption:@"cliqset"];
		}
}

// Put a phone record
-(void)putPhone:(NSString*)cid tag:(NSString*)tag number:(NSString*)number primary:(BOOL)primary {
	cliqsetAppDelegate* myApp = (cliqsetAppDelegate*)[[UIApplication sharedApplication] delegate];
	
	self.currentContact = (NSMutableString*)cid;
	self.currentType    = (NSMutableString*)tag;
	self.currentField   = (NSMutableString*)number;
	self.currentFlag    = (BOOL)primary;
	
	NSString *url = [@"" stringByAppendingFormat:@"https://api.cliqset.com/user/%@/contacts/%@/phones/%@", myApp.userString, cid, tag];
	
	NSString *primaryString = primary ? @"true" : @"false";
	
	NSMutableString * data = (NSMutableString*)[@"" stringByAppendingFormat:@"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><Phone><Type>%@</Type><PhoneNumber>%@</PhoneNumber><Primary>%@</Primary></Phone>", tag, number, primaryString];
	
	NSData* formData = [data dataUsingEncoding:NSASCIIStringEncoding];
	NSInteger dataLength = [formData length];
	NSString* dataLengthStr = [NSString stringWithFormat:@"%d", dataLength];
	
	Connector * connector = [[[Connector alloc] init] autorelease];
	
	connector.mode   = 8;
	connector.parent = self;
	
	connector.theRequest=(NSMutableURLRequest*)[NSMutableURLRequest requestWithURL:[NSURL URLWithString:url] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];	
	
	[connector.theRequest setHTTPMethod:@"PUT"];
	
	[connector.theRequest addValue:myApp.authenticationString forHTTPHeaderField:@"Authorization"];
	[connector.theRequest addValue:consumerKey forHTTPHeaderField:@"CliqsetConsumerKey"];
	[connector.theRequest addValue:@"application/xml" forHTTPHeaderField:@"Content-Type"];
	[connector.theRequest addValue:@"api.cliqset.com" forHTTPHeaderField:@"Host"];
	[connector.theRequest addValue:dataLengthStr forHTTPHeaderField:@"Content-Length"];
    [connector.theRequest setHTTPBody:(NSData*)formData];
	
	connector.theConnection=[[NSURLConnection alloc] initWithRequest:connector.theRequest delegate:connector];
	
	[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
	if (connector.theConnection) {
		connector.receivedData=[[NSMutableData data] retain];		
		} 
	else {
		[myApp addTextToLog:@"Could not connect to the network" withCaption:@"cliqset"];
		}
}

// Put an url record
-(void)putURL:(NSString*)cid tag:(NSString*)tag number:(NSString*)number primary:(BOOL)primary {
	cliqsetAppDelegate* myApp = (cliqsetAppDelegate*)[[UIApplication sharedApplication] delegate];
	
	self.currentContact = (NSMutableString*)cid;
	self.currentType    = (NSMutableString*)tag;
	self.currentField   = (NSMutableString*)number;
	self.currentFlag    = (BOOL)primary;
	
	NSString *url = [@"" stringByAppendingFormat:@"https://api.cliqset.com/user/%@/contacts/%@/urls/%@", myApp.userString, cid, tag];
	
	NSString *primaryString = primary ? @"true" : @"false";
	
	NSMutableString * data = (NSMutableString*)[@"" stringByAppendingFormat:@"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><URL><Type>%@</Type><URL>%@</URL><Primary>%@</Primary></URL>", tag, number, primaryString];
	
	NSData* formData = [data dataUsingEncoding:NSASCIIStringEncoding];
	NSInteger dataLength = [formData length];
	NSString* dataLengthStr = [NSString stringWithFormat:@"%d", dataLength];
	
	Connector * connector = [[[Connector alloc] init] autorelease];
	
	connector.mode   = 9;
	connector.parent = self;
	
	connector.theRequest=(NSMutableURLRequest*)[NSMutableURLRequest requestWithURL:[NSURL URLWithString:url] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];	
	
	[connector.theRequest setHTTPMethod:@"PUT"];
	
	[connector.theRequest addValue:myApp.authenticationString forHTTPHeaderField:@"Authorization"];
	[connector.theRequest addValue:consumerKey forHTTPHeaderField:@"CliqsetConsumerKey"];
	[connector.theRequest addValue:@"application/xml" forHTTPHeaderField:@"Content-Type"];
	[connector.theRequest addValue:@"api.cliqset.com" forHTTPHeaderField:@"Host"];
	[connector.theRequest addValue:dataLengthStr forHTTPHeaderField:@"Content-Length"];
    [connector.theRequest setHTTPBody:(NSData*)formData];
	
	connector.theConnection=[[NSURLConnection alloc] initWithRequest:connector.theRequest delegate:connector];
	
	[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
	if (connector.theConnection) {
		connector.receivedData=[[NSMutableData data] retain];		
		} 
	else {
		[myApp addTextToLog:@"Could not connect to the network" withCaption:@"cliqset"];
		}
}

// Put an email record
-(void)putEmail:(NSString*)cid tag:(NSString*)tag number:(NSString*)number primary:(BOOL)primary {
	cliqsetAppDelegate* myApp = (cliqsetAppDelegate*)[[UIApplication sharedApplication] delegate];
	
	self.currentContact = (NSMutableString*)cid;
	self.currentType    = (NSMutableString*)tag;
	self.currentField   = (NSMutableString*)number;
	self.currentFlag    = (BOOL)primary;
	
	NSString *url = [@"" stringByAppendingFormat:@"https://api.cliqset.com/user/%@/contacts/%@/emailaddresses/%@", myApp.userString, cid, tag];
	
	NSString *primaryString = primary ? @"true" : @"false";
	
	NSMutableString * data = (NSMutableString*)[@"" stringByAppendingFormat:@"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><EmailAddress><Type>%@</Type><Address>%@</Address><Primary>%@</Primary></EmailAddress>", tag, number, primaryString];
	
	NSData* formData = [data dataUsingEncoding:NSASCIIStringEncoding];
	NSInteger dataLength = [formData length];
	NSString* dataLengthStr = [NSString stringWithFormat:@"%d", dataLength];
	
	Connector * connector = [[[Connector alloc] init] autorelease];
	
	connector.mode   = 10;
	connector.parent = self;
	
	connector.theRequest=(NSMutableURLRequest*)[NSMutableURLRequest requestWithURL:[NSURL URLWithString:url] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];	
	
	[connector.theRequest setHTTPMethod:@"PUT"];
	
	[connector.theRequest addValue:myApp.authenticationString forHTTPHeaderField:@"Authorization"];
	[connector.theRequest addValue:consumerKey forHTTPHeaderField:@"CliqsetConsumerKey"];
	[connector.theRequest addValue:@"application/xml" forHTTPHeaderField:@"Content-Type"];
	[connector.theRequest addValue:@"api.cliqset.com" forHTTPHeaderField:@"Host"];
	[connector.theRequest addValue:dataLengthStr forHTTPHeaderField:@"Content-Length"];
    [connector.theRequest setHTTPBody:(NSData*)formData];
	
	connector.theConnection=[[NSURLConnection alloc] initWithRequest:connector.theRequest delegate:connector];
	
	[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
	if (connector.theConnection) {
		connector.receivedData=[[NSMutableData data] retain];		
		} 
	else {
		[myApp addTextToLog:@"Could not connect to the network" withCaption:@"cliqset"];
		}
}

// Put an IM record
-(void)putIM:(NSString*)cid tag:(NSString*)tag number:(NSString*)number primary:(BOOL)primary {
	cliqsetAppDelegate* myApp = (cliqsetAppDelegate*)[[UIApplication sharedApplication] delegate];
	
	self.currentContact = (NSMutableString*)cid;
	self.currentType    = (NSMutableString*)tag;
	self.currentField   = (NSMutableString*)number;
	self.currentFlag    = (BOOL)primary;
	
	NSString *url = [@"" stringByAppendingFormat:@"https://api.cliqset.com/user/%@/contacts/%@/ims/%@", myApp.userString, cid, tag];
	
	NSString *primaryString = primary ? @"true" : @"false";
	
	NSMutableString * data = (NSMutableString*)[@"" stringByAppendingFormat:@"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><IM><Network>%@</Network><Name>%@</Name><Primary>%@</Primary></IM>", tag, number, primaryString];
	
	NSData* formData = [data dataUsingEncoding:NSASCIIStringEncoding];
	NSInteger dataLength = [formData length];
	NSString* dataLengthStr = [NSString stringWithFormat:@"%d", dataLength];
	
	Connector * connector = [[[Connector alloc] init] autorelease];
	
	connector.mode   = 11;
	connector.parent = self;
	
	connector.theRequest=(NSMutableURLRequest*)[NSMutableURLRequest requestWithURL:[NSURL URLWithString:url] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];	
	
	[connector.theRequest setHTTPMethod:@"PUT"];
	
	[connector.theRequest addValue:myApp.authenticationString forHTTPHeaderField:@"Authorization"];
	[connector.theRequest addValue:consumerKey forHTTPHeaderField:@"CliqsetConsumerKey"];
	[connector.theRequest addValue:@"application/xml" forHTTPHeaderField:@"Content-Type"];
	[connector.theRequest addValue:@"api.cliqset.com" forHTTPHeaderField:@"Host"];
	[connector.theRequest addValue:dataLengthStr forHTTPHeaderField:@"Content-Length"];
    [connector.theRequest setHTTPBody:(NSData*)formData];
	
	connector.theConnection=[[NSURLConnection alloc] initWithRequest:connector.theRequest delegate:connector];
	
	[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
	if (connector.theConnection) {
		connector.receivedData=[[NSMutableData data] retain];		
		} 
	else {
		[myApp addTextToLog:@"Could not connect to the network" withCaption:@"cliqset"];
		}
}

// Put an Address record
-(void)putAddress:(NSString*)cid tag:(NSString*)tag street:(NSString*)street locality:(NSString*)locality region:(NSString*)region postalCode:(NSString*)postalCode country:(NSString *)country {
	cliqsetAppDelegate* myApp = (cliqsetAppDelegate*)[[UIApplication sharedApplication] delegate];
	
	self.currentContact    = (NSMutableString*)cid;
	self.currentType       = (NSMutableString*)tag;
	self.currentStreet     = (NSMutableString*)street;
	self.currentLocality   = (NSMutableString*)locality;
	self.currentRegion     = (NSMutableString*)region;
	self.currentPostalCode = (NSMutableString*)postalCode;
	self.currentCountry    = (NSMutableString*)country;
	
	NSString *url = [@"" stringByAppendingFormat:@"https://api.cliqset.com/user/%@/contacts/%@/addresses/%@", myApp.userString, cid, tag];
		
	NSMutableString * data = (NSMutableString*)[@"" stringByAppendingFormat:@"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><Address><Type>%@</Type><Primary>true</Primary><StreetAddress>%@</StreetAddress><Locality>%@</Locality><Region>%@</Region><Country>%@</Country><PostCode>%@</PostCode></Address>", tag, street, locality, region, country, postalCode];
	
	NSData* formData = [data dataUsingEncoding:NSASCIIStringEncoding];
	NSInteger dataLength = [formData length];
	NSString* dataLengthStr = [NSString stringWithFormat:@"%d", dataLength];
	
	Connector * connector = [[[Connector alloc] init] autorelease];
	
	connector.mode   = 12;
	connector.parent = self;
	
	connector.theRequest=(NSMutableURLRequest*)[NSMutableURLRequest requestWithURL:[NSURL URLWithString:url] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];	
	
	[connector.theRequest setHTTPMethod:@"PUT"];
	
	[connector.theRequest addValue:myApp.authenticationString forHTTPHeaderField:@"Authorization"];
	[connector.theRequest addValue:consumerKey forHTTPHeaderField:@"CliqsetConsumerKey"];
	[connector.theRequest addValue:@"application/xml" forHTTPHeaderField:@"Content-Type"];
	[connector.theRequest addValue:@"api.cliqset.com" forHTTPHeaderField:@"Host"];
	[connector.theRequest addValue:dataLengthStr forHTTPHeaderField:@"Content-Length"];
    [connector.theRequest setHTTPBody:(NSData*)formData];
	
	connector.theConnection=[[NSURLConnection alloc] initWithRequest:connector.theRequest delegate:connector];
	
	[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
	if (connector.theConnection) {
		connector.receivedData=[[NSMutableData data] retain];		
		} 
	else {
		[myApp addTextToLog:@"Could not connect to the network" withCaption:@"cliqset"];
		}
}

// Put a Contact record
-(void)putContact:(Contact*)contact {
	cliqsetAppDelegate* myApp = (cliqsetAppDelegate*)[[UIApplication sharedApplication] delegate];
	
	self.currentContactRecord = contact;
	
	NSString *url;
	if (contact.contactIdentifier != nil) {
		url = [@"" stringByAppendingFormat:@"https://api.cliqset.com/user/%@/contacts/%@", myApp.userString, contact.contactIdentifier];
	  }
	else {
		url = [@"" stringByAppendingFormat:@"https://api.cliqset.com/user/%@/contacts", myApp.userString];
	}

	[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
	// Start constructing contact record.
	NSMutableString* data = @"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><Contact>";
	
	data = (NSMutableString*)[data stringByAppendingFormat:@"<GivenName>%@</GivenName>", contact.givenName == nil ? @"" : contact.givenName];
	data = (NSMutableString*)[data stringByAppendingFormat:@"<MiddleName>%@</MiddleName>", contact.middleName == nil ? @"" : contact.middleName];
	data = (NSMutableString*)[data stringByAppendingFormat:@"<FamilyName>%@</FamilyName>", contact.familyName == nil ? @"" : contact.familyName];
	data = (NSMutableString*)[data stringByAppendingFormat:@"<Notes>%@</Notes>", contact.notes == nil ? @"" : contact.notes];
	data = (NSMutableString*)[data stringByAppendingFormat:@"<Company>%@</Company>", contact.company == nil ? @"" : contact.company];
	data = (NSMutableString*)[data stringByAppendingFormat:@"<Position>%@</Position>", contact.position == nil ? @"" : contact.position];
	data = (NSMutableString*)[data stringByAppendingFormat:@"<PhotoUrl>%@</PhotoUrl>", contact.photoURL == nil ? @"" : contact.photoURL];

	// Build email addresses
	data = (NSMutableString*)[data stringByAppendingString:@"<EmailAddresses>"];
	for (int x=0; x<[contact.emailAddresses count]; x++) {
		data = (NSMutableString*)[data stringByAppendingString:@"<EmailAddress>"];
		EmailAddress * email = (EmailAddress *)[contact.emailAddresses objectAtIndex:x];
		data = (NSMutableString*)[data stringByAppendingFormat:@"<Type>%@</Type>", email.type == nil ? @"" : email.type];
		data = (NSMutableString*)[data stringByAppendingFormat:@"<Address>%@</Address>", email.address == nil ? @"" : email.address];
		data = (NSMutableString*)[data stringByAppendingFormat:@"<Primary>%@</Primary>", (email.primary == 0) ? @"false" : @"true"];
		data = (NSMutableString*)[data stringByAppendingString:@"</EmailAddress>"];
	}
	data = (NSMutableString*)[data stringByAppendingString:@"</EmailAddresses>"];
	
	// Build Addresses
	data = (NSMutableString*)[data stringByAppendingString:@"<Addresses>"];
	for (int x=0; x<[contact.addresses count]; x++) {
		data = (NSMutableString*)[data stringByAppendingString:@"<Address>"];
		Address * address = (Address *)[contact.addresses objectAtIndex:x];
		data = (NSMutableString*)[data stringByAppendingFormat:@"<Type>%@</Type>", address.type == nil ? @"" : address.type];
		data = (NSMutableString*)[data stringByAppendingFormat:@"<Primary>%@</Primary>", (address.primary == 0) ? @"false" : @"true"];
		data = (NSMutableString*)[data stringByAppendingFormat:@"<StreetAddress>%@</StreetAddress>", address.streetAddress == nil ? @"" : address.streetAddress];
		data = (NSMutableString*)[data stringByAppendingFormat:@"<Locality>%@</Locality>", address.locality == nil ? @"" : address.locality];
		data = (NSMutableString*)[data stringByAppendingFormat:@"<Region>%@</Region>", address.region == nil ? @"" : address.region];
		data = (NSMutableString*)[data stringByAppendingFormat:@"<PostCode>%@</PostCode>", address.postalCode == nil ? @"" : address.postalCode];
		data = (NSMutableString*)[data stringByAppendingFormat:@"<Country>%@</Country>", address.country == nil ? @"" : address.country];
		data = (NSMutableString*)[data stringByAppendingString:@"</Address>"];
	}
	data = (NSMutableString*)[data stringByAppendingString:@"</Addresses>"];
	
	// Build IMs
	data = (NSMutableString*)[data stringByAppendingString:@"<IMs>"];
	for (int x=0; x<[contact.imScreenNames count]; x++) {
		data = (NSMutableString*)[data stringByAppendingString:@"<IM>"];
		IM * im = (IM *)[contact.imScreenNames objectAtIndex:x];
		data = (NSMutableString*)[data stringByAppendingFormat:@"<Network>%@</Network>", im.network == nil ? @"" : [[[[[[im.network stringByReplacingOccurrencesOfString:@"Aim" withString:@"AIM" ] stringByReplacingOccurrencesOfString:@"Gtalk" withString:@"GTalk"] stringByReplacingOccurrencesOfString:@"Icq" withString:@"ICQ"] stringByReplacingOccurrencesOfString:@"Xmpp" withString:@"XMPP"] stringByReplacingOccurrencesOfString:@"Qq" withString:@"QQ"] stringByReplacingOccurrencesOfString:@"Msn" withString:@"MSN"]];
		data = (NSMutableString*)[data stringByAppendingFormat:@"<Name>%@</Name>", im.name == nil ? @"" : im.name];
		data = (NSMutableString*)[data stringByAppendingFormat:@"<Primary>%@</Primary>", (im.primary == 0) ? @"false" : @"true"];
		data = (NSMutableString*)[data stringByAppendingString:@"</IM>"];
	}
	data = (NSMutableString*)[data stringByAppendingString:@"</IMs>"];
	
	// Build Phones
	data = (NSMutableString*)[data stringByAppendingString:@"<Phones>"];
	for (int x=0; x<[contact.phones count]; x++) {
		data = (NSMutableString*)[data stringByAppendingString:@"<Phone>"];
		Phone * phone = (Phone *)[contact.phones objectAtIndex:x];
		data = (NSMutableString*)[data stringByAppendingFormat:@"<Type>%@</Type>", phone.type == nil ? @"" : phone.type];
		data = (NSMutableString*)[data stringByAppendingFormat:@"<PhoneNumber>%@</PhoneNumber>", phone.phoneNumber == nil ? @"" : phone.phoneNumber];
		data = (NSMutableString*)[data stringByAppendingFormat:@"<Primary>%@</Primary>", (phone.primary == 0) ? @"false" : @"true"];
		data = (NSMutableString*)[data stringByAppendingString:@"</Phone>"];
	}
	data = (NSMutableString*)[data stringByAppendingString:@"</Phones>"];
	
	// Build URLs
	data = (NSMutableString*)[data stringByAppendingString:@"<URLs>"];
	for (int x=0; x<[contact.urls count]; x++) {
		data = (NSMutableString*)[data stringByAppendingString:@"<URL>"];
		URL * url = (URL *)[contact.urls objectAtIndex:x];
		data = (NSMutableString*)[data stringByAppendingFormat:@"<Type>%@</Type>", url.type == nil ? @"" : url.type];
		data = (NSMutableString*)[data stringByAppendingFormat:@"<URL>%@</URL>", url.url == nil ? @"" : url.url];
		data = (NSMutableString*)[data stringByAppendingFormat:@"<Primary>%@</Primary>", (url.primary == 0) ? @"false" : @"true"];
		data = (NSMutableString*)[data stringByAppendingString:@"</URL>"];
	}
	data = (NSMutableString*)[data stringByAppendingString:@"</URLs>"];
	
	// Cap off the contact element
	data = (NSMutableString*)[data stringByAppendingString:@"</Contact>"];
	
	NSData* formData = [data dataUsingEncoding:NSASCIIStringEncoding];
	NSInteger dataLength = [formData length];
	NSString* dataLengthStr = [NSString stringWithFormat:@"%d", dataLength];
	
	Connector * connector = [[[Connector alloc] init] autorelease];
	
	connector.mode   = 13;
	connector.parent = self;
	
	connector.theRequest=(NSMutableURLRequest*)[NSMutableURLRequest requestWithURL:[NSURL URLWithString:url] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];	
	
	if (contact.contactIdentifier!=nil) {
		[connector.theRequest setHTTPMethod:@"PUT"];
		} 
	else {
		[connector.theRequest setHTTPMethod:@"POST"];
	}
	
	[connector.theRequest addValue:myApp.authenticationString forHTTPHeaderField:@"Authorization"];
	[connector.theRequest addValue:consumerKey forHTTPHeaderField:@"CliqsetConsumerKey"];
	[connector.theRequest addValue:@"application/xml" forHTTPHeaderField:@"Content-Type"];
	[connector.theRequest addValue:@"api.cliqset.com" forHTTPHeaderField:@"Host"];
	[connector.theRequest addValue:dataLengthStr forHTTPHeaderField:@"Content-Length"];
    [connector.theRequest setHTTPBody:(NSData*)formData];
	
	connector.theConnection=[[NSURLConnection alloc] initWithRequest:connector.theRequest delegate:connector];
	
	if (connector.theConnection) {
		connector.receivedData=[[NSMutableData data] retain];		
		} 
	else {
		[myApp addTextToLog:@"Could not connect to the network" withCaption:@"cliqset"];
		}
}

// Load up events array
-(void)loadToEvents {
	cliqsetAppDelegate* myApp = (cliqsetAppDelegate*)[[UIApplication sharedApplication] delegate];
	
	NSString *url;
	
	if (myApp.userString == nil) {return;}

	if ([myApp.database countEventsFromDatabase] == 0) {
		url = [@"" stringByAppendingFormat:@"https://api.cliqset.com/user/%@/events/to?count=25", myApp.userString];
	} else {
		url = [@"" stringByAppendingFormat:@"https://api.cliqset.com/user/%@/events/to?count=25&createdsince=%@", myApp.userString, [myApp.database getLatestEventDateFromDatabase]];
	}
	
	Connector * connector = [[[Connector alloc] init] autorelease];
	
	connector.mode   = 14;
	connector.parent = self;
	
	connector.theRequest=(NSMutableURLRequest*)[NSMutableURLRequest requestWithURL:[NSURL URLWithString:url] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];	
	
	[connector.theRequest setHTTPMethod:@"GET"];
	
	[connector.theRequest addValue:myApp.authenticationString forHTTPHeaderField:@"Authorization"];
	[connector.theRequest addValue:consumerKey forHTTPHeaderField:@"CliqsetConsumerKey"];
	
	connector.theConnection=[[NSURLConnection alloc] initWithRequest:connector.theRequest delegate:connector];
	
	[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
	[myApp showEventsHoverView:YES];
	
	if (connector.theConnection) {
		connector.receivedData=[[NSMutableData data] retain];				
	} 
	else {
		[myApp addTextToLog:@"Could not connect to the network" withCaption:@"cliqset"];
		}
}

// Load up From events array
-(void)loadFromEvents:(NSString*)uid reload:(BOOL)reload {
	cliqsetAppDelegate* myApp = (cliqsetAppDelegate*)[[UIApplication sharedApplication] delegate];
	
	if (myApp.userString == nil) {return;}
	
	NSString *url = [@"" stringByAppendingFormat:@"https://api.cliqset.com/user/%@/events/from?count=10", uid];
	
	Connector * connector = [[[Connector alloc] init] autorelease];
	
	connector.mode   = 15;
	connector.parent = self;
	
	connector.theRequest=(NSMutableURLRequest*)[NSMutableURLRequest requestWithURL:[NSURL URLWithString:url] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];	
	
	[connector.theRequest setHTTPMethod:@"GET"];
	
	[connector.theRequest addValue:myApp.authenticationString forHTTPHeaderField:@"Authorization"];
	[connector.theRequest addValue:consumerKey forHTTPHeaderField:@"CliqsetConsumerKey"];
	
	connector.theConnection=[[NSURLConnection alloc] initWithRequest:connector.theRequest delegate:connector];
	
	[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
	[myApp showEventsHoverView:YES];
	
	if (connector.theConnection) {
		connector.receivedData=[[NSMutableData data] retain];		
		} 
	else {
		[myApp addTextToLog:@"Could not connect to the network" withCaption:@"cliqset"];
		}	
}

// Load up Profile events array
-(void)loadProfileEvents:(NSString*)uid reload:(BOOL)reload {
	cliqsetAppDelegate* myApp = (cliqsetAppDelegate*)[[UIApplication sharedApplication] delegate];
	
	if (myApp.userString == nil) {return;}
	
	NSString *url = [@"" stringByAppendingFormat:@"https://api.cliqset.com/user/%@/events/from?count=10", uid];
	
	Connector * connector = [[[Connector alloc] init] autorelease];
	
	connector.mode   = 19;
	connector.parent = self;
	
	connector.theRequest=(NSMutableURLRequest*)[NSMutableURLRequest requestWithURL:[NSURL URLWithString:url] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];	
	
	[connector.theRequest setHTTPMethod:@"GET"];
	
	[connector.theRequest addValue:myApp.authenticationString forHTTPHeaderField:@"Authorization"];
	[connector.theRequest addValue:consumerKey forHTTPHeaderField:@"CliqsetConsumerKey"];
	
	connector.theConnection=[[NSURLConnection alloc] initWithRequest:connector.theRequest delegate:connector];
	
	[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
	[myApp showProfileHoverView:YES];
	
	if (connector.theConnection) {
		connector.receivedData=[[NSMutableData data] retain];		
		} 
	else {
		[myApp addTextToLog:@"Could not connect to the network" withCaption:@"cliqset"];
		}	
}

// Get current status
-(void)getCurrentStatus {
	cliqsetAppDelegate* myApp = (cliqsetAppDelegate*)[[UIApplication sharedApplication] delegate];
	
	if (myApp.userString == nil) {return;}
	
	NSString *url = [@"" stringByAppendingFormat:@"https://api.cliqset.com/user/%@/status", myApp.userString];

	Connector * connector = [[[Connector alloc] init] autorelease];
	
	connector.mode   = 16;
	connector.parent = self;
	
	connector.theRequest=(NSMutableURLRequest*)[NSMutableURLRequest requestWithURL:[NSURL URLWithString:url] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];	
	
	[connector.theRequest setHTTPMethod:@"GET"];
	
	[connector.theRequest addValue:myApp.authenticationString forHTTPHeaderField:@"Authorization"];
	[connector.theRequest addValue:consumerKey forHTTPHeaderField:@"CliqsetConsumerKey"];
	
	connector.theConnection=[[NSURLConnection alloc] initWithRequest:connector.theRequest delegate:connector];
	
	[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
	
	if (connector.theConnection) {
		connector.receivedData=[[NSMutableData data] retain];		
		} 
	else {
		[myApp addTextToLog:@"Could not connect to the network" withCaption:@"cliqset"];
		}
}

// Put current status
-(void)putCurrentStatus:(NSString*)status {
	cliqsetAppDelegate* myApp = (cliqsetAppDelegate*)[[UIApplication sharedApplication] delegate];
	
	if (myApp.userString == nil) {return;}
	
	myApp.currentStatus = (NSMutableString *)status;
	
	NSString *url = [@"" stringByAppendingFormat:@"https://api.cliqset.com/user/%@/status", myApp.userString];

	Connector * connector = [[[Connector alloc] init] autorelease];
	
	connector.mode   = 17;
	connector.parent = self;
	
	connector.theRequest=(NSMutableURLRequest*)[NSMutableURLRequest requestWithURL:[NSURL URLWithString:url] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];	
	
	NSMutableString * data = (NSMutableString*)[@"" stringByAppendingFormat:@"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><Status>%@</Status>", status];
	
	NSData* formData = [data dataUsingEncoding:NSASCIIStringEncoding];
	NSInteger dataLength = [formData length];
	NSString* dataLengthStr = [NSString stringWithFormat:@"%d", dataLength];
	
	[connector.theRequest setHTTPMethod:@"PUT"];
	
	[connector.theRequest addValue:myApp.authenticationString forHTTPHeaderField:@"Authorization"];
	[connector.theRequest addValue:consumerKey forHTTPHeaderField:@"CliqsetConsumerKey"];
	[connector.theRequest addValue:@"application/xml" forHTTPHeaderField:@"Content-Type"];
	[connector.theRequest addValue:@"api.cliqset.com" forHTTPHeaderField:@"Host"];
	[connector.theRequest addValue:dataLengthStr forHTTPHeaderField:@"Content-Length"];
    [connector.theRequest setHTTPBody:(NSData*)formData];
	
	connector.theConnection=[[NSURLConnection alloc] initWithRequest:connector.theRequest delegate:connector];
	
	[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
	[myApp showProfileHoverView:YES];
	
	if (connector.theConnection) {
		connector.receivedData=[[NSMutableData data] retain];		
		} 
	else {
		[myApp addTextToLog:@"Could not connect to the network" withCaption:@"cliqset"];
		}
}

// Get user profile
-(void)getProfile {
	cliqsetAppDelegate* myApp = (cliqsetAppDelegate*)[[UIApplication sharedApplication] delegate];
	
	if (myApp.userString == nil) {return;}
	
	NSString *url = [@"" stringByAppendingFormat:@"https://api.cliqset.com/user/%@/profile", myApp.userString];

	Connector * connector = [[[Connector alloc] init] autorelease];
	
	connector.mode   = 18;
	connector.parent = self;
	
	connector.theRequest=(NSMutableURLRequest*)[NSMutableURLRequest requestWithURL:[NSURL URLWithString:url] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];	
	
	[connector.theRequest setHTTPMethod:@"GET"];
	
	[connector.theRequest addValue:myApp.authenticationString forHTTPHeaderField:@"Authorization"];
	[connector.theRequest addValue:consumerKey forHTTPHeaderField:@"CliqsetConsumerKey"];
	
	connector.theConnection=[[NSURLConnection alloc] initWithRequest:connector.theRequest delegate:connector];
	
	[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
	
	if (connector.theConnection) {
		connector.receivedData=[[NSMutableData data] retain];		
		} 
	else {
		[myApp addTextToLog:@"Could not connect to the network" withCaption:@"cliqset"];
		}	
}

// Release cliqset
-(void)dealloc {
	[currentContactRecord release];
	[currentStreet release];
	[currentLocality release];
	[currentRegion release];
	[currentPostalCode release];
	[currentCountry release];
	
	[currentContact release];
	[currentType release];
	[super dealloc];
}

@end
